﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace JESAI.CmdTool.Helpers
{
    public class CMDHelper
    {
        private readonly ProcessStartInfo PROCES_INFO;

        public CMDHelper((string key, string value)[] EnvironmentVariable = null, bool createNoWindow = true, bool redirectStandardOutput = true)
        {
            PROCES_INFO = new ProcessStartInfo()
            {
                FileName = "cmd.exe",
                RedirectStandardOutput = redirectStandardOutput,
                CreateNoWindow = createNoWindow
            };
            SetEnvVariables___(EnvironmentVariable);
        }

        public List<string> Run(string command)
        {
            return Run___(command);
        }

        private List<string> Run___(string command)
        {
            List<string> ret = new List<string>();

            PROCES_INFO.Arguments = "/C " + command;

            var proc = new Process()
            {
                StartInfo = PROCES_INFO
            };

            proc.Start();

            while (!proc.StandardOutput.EndOfStream)
            {
                ret.Add(proc.StandardOutput.ReadLine());
            }

            if (proc.ExitCode != 0)
            {
                throw new Exception($"Exit code: '{proc.ExitCode}' for command: '{command}'");
            }

            return ret;
        }

        private void SetEnvVariables___((string key, string value)[] EnvVariable)
        {
            if (EnvVariable == null)
            {
                return;
            }

            foreach (var item in EnvVariable)
            {
                if (PROCES_INFO.EnvironmentVariables.ContainsKey(item.key))
                {
                    var value = PROCES_INFO.EnvironmentVariables[item.key];

                    PROCES_INFO.EnvironmentVariables.Remove(item.key);

                    PROCES_INFO.EnvironmentVariables.Add(item.key,
                        $"{value};{item.value}"
                    );
                }
                else
                {
                    PROCES_INFO.EnvironmentVariables.Add(item.key, item.value);
                }
            }
        }

        public static string ExeCommand(string commandText)
        {
            return ExeCommand(new string[] { commandText });
        }
        public static string ExeCommand(string[] commandTexts)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            string strOutput = null;
            try
            {
                p.Start();
                foreach (string item in commandTexts)
                {
                    p.StandardInput.WriteLine(item);
                }
                p.StandardInput.WriteLine("exit");
                strOutput = p.StandardOutput.ReadToEnd();
                //strOutput = Encoding.UTF8.GetString(Encoding.Default.GetBytes(strOutput));
                p.WaitForExit();
                p.Close();
            }
            catch (Exception e)
            {
                strOutput = e.Message;
            }
            return strOutput;
        }
        public static bool StartApp(string appName)
        {
            return StartApp(appName, ProcessWindowStyle.Hidden);
        }
        public static bool StartApp(string appName, ProcessWindowStyle style)
        {
            return StartApp(appName, null, style);
        }
        public static bool StartApp(string appName, string arguments)
        {
            return StartApp(appName, arguments, ProcessWindowStyle.Hidden);
        }
        public static bool StartApp(string appName, string arguments, ProcessWindowStyle style)
        {
            bool blnRst = false;
            Process p = new Process();
            p.StartInfo.FileName = appName;
            p.StartInfo.WindowStyle = style;
            p.StartInfo.Arguments = arguments;
            try
            {
                p.Start();
                p.WaitForExit();
                p.Close();
                blnRst = true;
            }
            catch
            {
            }
            return blnRst;
        }
    }
}
